package com.bignerdranch.android.criminalintent;

import java.util.ArrayList;

import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;

public class CrimeListFragment extends ListFragment {
	private ArrayList<Crime> mCrimes;
	private boolean mSubtitleVisible;
	private ListView mListView;
    private Callbacks mCallbacks;
    
    /**
     * Required interface for hosting activities
     */
    public interface Callbacks{
    	void onCrimeSelected(Crime crime);
    }
    
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		mCallbacks = (Callbacks) activity;
	}

	@Override
	public void onDetach() {
		super.onDetach();
		mCallbacks = null;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setHasOptionsMenu(true);

		mCrimes = CrimeLab.get(getActivity()).getCrimes();

		setRetainInstance(true);
		mSubtitleVisible = false;
	}

	@TargetApi(11)
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.crime_list_fragment, container,
				false);

		mListView = (ListView) v.findViewById(android.R.id.list);
		CrimeAdapter adapter = new CrimeAdapter(mCrimes);
		mListView.setAdapter(adapter);
		View emptView = v.findViewById(android.R.id.empty);
		mListView.setEmptyView(emptView);

		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
			if (mSubtitleVisible) {
				getActivity().getActionBar().setSubtitle(R.string.subtitle);
			}
			mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
		} else {
			registerForContextMenu(mListView);
		}
		getActivity().setTitle(R.string.crime_title);

		mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

			public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
				return false;
			}

			public void onDestroyActionMode(ActionMode arg0) {
			}

			public void onItemCheckedStateChanged(ActionMode mode,
					int position, long id, boolean checked) {
			}

			public boolean onCreateActionMode(ActionMode mode, Menu menu) {
				MenuInflater inflater = mode.getMenuInflater();
				inflater.inflate(R.menu.crime_list_item_context, menu);
				return true;
			}

			public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
				switch (item.getItemId()) {
				case R.id.menu_item_delete_crime:
					CrimeAdapter adapter = (CrimeAdapter) mListView
							.getAdapter();
					CrimeLab lab = CrimeLab.get(getActivity());
					for (int i = adapter.getCount(); i >= 0; i--) {
						if (mListView.isItemChecked(i)) {
							lab.deleteCrime(adapter.getItem(i));
						}
					}
					mode.finish();
					lab.saveCrimes();
					adapter.notifyDataSetChanged();
					return true;
				default:
					return false;
				}
			}
		});
		return v;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.menu_item_new_crime:
			Crime c = new Crime();
			CrimeLab.get(getActivity()).addCrime(c);
			CrimeAdapter adapter = (CrimeAdapter) mListView.getAdapter();
			adapter.notifyDataSetChanged();
			mCallbacks.onCrimeSelected(c);
			return true;
		case R.id.menu_item_show_subtitle:
			if (getActivity().getActionBar().getSubtitle() == null) {
				getActivity().getActionBar().setSubtitle(R.string.subtitle);
				item.setTitle(R.string.hide_subtitle);
				mSubtitleVisible = true;
			} else {
				getActivity().getActionBar().setSubtitle(null);
				item.setTitle(R.string.show_subtitle);
				mSubtitleVisible = false;
			}
			return true;
		default:
			return false;
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context,
				menu);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		int position = info.position;
		CrimeAdapter adapter = (CrimeAdapter) mListView.getAdapter();
		Crime c = adapter.getItem(position);

		switch (item.getItemId()) {
		case R.id.menu_item_delete_crime:
			CrimeLab lab = CrimeLab.get(getActivity());
			lab.deleteCrime(c);
			adapter.notifyDataSetChanged();
			break;
		}

		return super.onContextItemSelected(item);
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		inflater.inflate(R.menu.fragment_crime_list, menu);

		MenuItem showSubtitle = menu.findItem(R.id.menu_item_show_subtitle);
		if (mSubtitleVisible && showSubtitle != null) {
			showSubtitle.setTitle(R.string.hide_subtitle);
		}
	}

	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		Crime c = ((CrimeAdapter) mListView.getAdapter()).getItem(position);

		mCallbacks.onCrimeSelected(c);
	}

	@Override
	public void onResume() {
		super.onResume();
		((CrimeAdapter) getListView().getAdapter()).notifyDataSetChanged();
	}

	public void updateUI(){
		((CrimeAdapter) getListView().getAdapter()).notifyDataSetChanged();
	}
	
	private class CrimeAdapter extends ArrayAdapter<Crime> {

		public CrimeAdapter(ArrayList<Crime> crimes) {
			super(getActivity(), 0, crimes);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// If we weren't given a view, inflate one
			if (convertView == null) {
				convertView = getActivity().getLayoutInflater().inflate(
						R.layout.list_item_crime, null);
			}

			// Configure the view for this crime
			Crime c = getItem(position);

			TextView title = (TextView) convertView
					.findViewById(R.id.crime_list_item_titleTextView);
			title.setText(c.getTitle());
			TextView dt = (TextView) convertView
					.findViewById(R.id.crime_list_item_dateTextView);
			dt.setText(c.getDate().toString());
			CheckBox solved = (CheckBox) convertView
					.findViewById(R.id.crime_list_item_solvedCheckBox);
			solved.setChecked(c.isSolved());

			return convertView;
		}

	}

}
